#!/usr/bin/env python
# -*- coding: UTF-8 -*-

"""
Este modulo lee un conjunto de numeros telefonicos
para ser consultados desde la base de datos.  Luego se genera un archivo html
con un resume y detalle de cada llamada.  Finalmente, el archivo es enviado
por correo electronico a cada dueno de telefono
@authors: Enrique Nunez
@contact: enunezf en gmail punto com
"""

import sys
import getpass
import pyodbc
import smtplib
from plantilla_cuenta import plantilla_cuenta
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

cfgbase = {'servidor':'xxx.xxx.xxx.xxx', 'usuario':'miusuario', 'clave':'miclave', \
           'base':'mibase'}

moviles = ['55555555','66666666',] 

duenos = {'55555555':'mio',\
            '66666666':'otro'}

correos = {'mio': ['micorreo1@micorreo.cl', 'micorreo2@micorreo.cl'], \
            'otro': ['otro@otrocorreo.cl']
            }

def conectasql():
    """
    Realiza a conexion a la base de datos y devuelve un objeto de conexion
    """
    cadenarandom = 'DRIVER={SQL Server};SERVER=' + cfgbase['servidor'] +\
                    ';DATABASE=' + cfgbase['base'] + \
                    ';UID=' + cfgbase['usuario'] +\
                    ';PWD=' + cfgbase['clave'] 
    cnn = pyodbc.connect(cadenarandom)
    return cnn

    
def cunsultatotales(movil, ano, mes):
    """
    Consulta la sumatoria de los valores y sobre cargo para cada movil
    agrupado por item para el ano - mes solicitado.
    @param movil: numero de movil
    @param ano: ano del periodo
    @param mes: mes del periodo
    """
    sql = """
    select item, sum(convert(int,valor)) as valor, sum(convert(int,sobrecargo)) as sobrecargo
    from llamados
    where fecha is not null
        and movil = ?
        and year(convert(datetime,(fecha + ' ' + hora),103)) = ?
        and month(convert(datetime,(fecha + ' ' + hora),103)) = ?
    group by item
    """
    cnn = conectasql()
    rst = cnn.cursor()
    rst.execute(sql, movil, ano, mes)
    filas = rst.fetchall()
    return filas

def cunsultadetalle(movil, ano, mes):
    """
    Consulta el detalle de llamadas para cada movil 
    para el ano - mes solicitado.
    @param movil: numero de movil
    @param ano: ano del periodo
    @param mes: mes del periodo
    """
    sql = """
        select
            item,concepto, discado, 
            destino, 
            convert(datetime,(fecha + ' ' + hora),103) as fecha,
            duracion, unidad, valor, 
            sobrecargo
        from llamados
        where fecha is not null
        and movil = ?
        and year(convert(datetime,(fecha + ' ' + hora),103)) = ?
        and month(convert(datetime,(fecha + ' ' + hora),103)) = ?
        order by  movil, item, convert(datetime,(fecha + ' ' + hora),103)
    """
    cnn = conectasql()
    rst = cnn.cursor()
    rst.execute(sql, movil, ano, mes)
    filas = rst.fetchall()
    return filas

def creahtml(movil, ano, mes, archivo):
    """
    Genera los archivo html de salida desde esta función son llamadas las
    funciones:
        - cunsultatotales
        - cunsultadetalle
    Observaciones
    =============
        Para compilar la plantilla
            - cp plantilla_cuenta.html plantilla_cuenta.tmpl
            - cheetah compile plantilla_cuenta.tmpl

    @param movil: numero de movil
    @param ano: ano del periodo
    @param mes: mes del periodo
    @param archivo: archivo de salida

    """
    #para compilar la plantilla
    #cp plantilla_cuenta.html plantilla_cuenta.tmpl
    #cheetah compile plantilla_cuenta.tmpl
    resumen = cunsultatotales(movil,ano,mes)
    phtml = plantilla_cuenta()
    phtml.titulo = 'Movil ' + str(movil)
    phtml.movil = str(movil)
    phtml.ano = str(ano)
    phtml.mes = str(mes)
    phtml.resumen = resumen
    neto = 0
    iva = 0
    total = 0
    for r in resumen:
        neto = neto + (r.valor + r.sobrecargo)
    iva = int(round(neto * 0.19,0))
    total = neto + iva
    phtml.neto = neto
    phtml.iva = iva
    phtml.total = total
    detalle = cunsultadetalle(movil, ano, mes)
    phtml.detalle = detalle
    open(archivo, 'w').write(str(phtml))

def enviacorreo(clave, destino, archivo, asunto, texto):
    """
    Envia correo electronico, utiliza cuenta y servidor de gmail
    se adjuntan el archivo de salida y el texto de cuerpo de correo.
    
    @param clave: contrasena de correo de salida
    @param destino: lista de correos de salida
    @param archivo: archivo html adjunto al correo
    @param asunto: asunto del correo
    @param texto: cuerpo del mensaje
    """
    mailServer = smtplib.SMTP('smtp.gmail.com',587)
    mailServer.starttls()
    mailServer.login('micorreo@gmail.com',clave)
    envios = ', '
    mensaje = MIMEMultipart()
    mensaje['From']='micorreo@gmail.com'
    mensaje['To']=envios.join(destino)
    mensaje['Subject']= asunto
    
    cuerpo = MIMEText(texto, 'plain')
    mensaje.attach(cuerpo)
    
    fp = open(archivo,'r')
    html = MIMEText(fp.read(), _subtype='html')
    fp.close()
    html.add_header('Content-Disposition', 'attachment', filename=archivo)
    mensaje.attach(html)

    mailServer.sendmail('micorreo@gmail.com',destino,mensaje.as_string())
    mailServer.close()
    

if __name__ == '__main__':
    ano = 'AAAA'
    mes = 'MM'
    #if (len(sys.argv) > 1):
    #    clave = sys.argv[1]
    #else:
    #    clave = getpass.getpass()

    for movil in moviles:
        #1.- lee movil y recupera dueno y correo
        dueno = duenos[movil]
        correo = correos[dueno]
        archivo = 'detalle' + movil + '_' + ano + mes + '.html'    
        #2.- crea archivos de salida
        creahtml(movil,ano,mes,archivo)
        #3.- envia correo
        #asunto = 'Cuenta teléfono ' + movil + ' periodo ' + ano + '-' + mes
        #texto = dueno + '\n' + 'te adjunto resumen y detalle de llamadas'
        #texto = texto + ' del periodo indicado\nSaludos\nENF'
        #enviacorreo(clave, correo, archivo, asunto, texto)

